 bondscell_results $65151aba-d946-401d-8cca-1874f38146f2queued¤logsrunning¦outputbodys<div class="markdown"><h1 id="Matrix-Multiplication-&#40;-*-Operator&#41;">Matrix Multiplication &#40; <code>*</code> Operator&#41;</h1>
<p>We just learned that <code>A .* B</code> is the element-wise product.</p>
<p>So, how is matrix multiplication performed, as in linear algebra?</p>
<p>We use the asterisk &#40;<code>*</code>&#41; operator without the dot.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA}QQTpersist_js_state·has_pluto_hook_features§cell_id$65151aba-d946-401d-8cca-1874f38146f2depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$e26b69c9-d37d-449d-90d4-cdce4dff2362queued¤logsrunning¦outputbody<div class="markdown"><h1 id="Problems">Problems</h1>
<div class="admonition tip"><p class="admonition-title">Remember that you can get help either through `?` in a REPL or with "Live Docs" right here in Pluto (lower right-hand corner)</p></div>
</div>mimetext/htmlrootassigneelast_run_timestampA}QR6persist_js_state·has_pluto_hook_features§cell_id$e26b69c9-d37d-449d-90d4-cdce4dff2362depends_on_disabled_cells§runtime 	published_object_keysdepends_on_skipped_cells§errored$1416a80e-dbda-4185-8984-7f5de3c58f02queued¤logsrunning¦outputbody<div class="markdown"><h2 id="5:-Array-Fusion">5: Array Fusion</h2>
<div class="admonition warning"><p class="admonition-title"></p><ul>
<li><p>Create three 1D vectors, <code>a</code>, <code>b</code>, and <code>c</code>, each of length 4.</p>
</li>
<li><p>Using a single, &quot;fused&quot; broadcast expression, calculate <span class="tex">$&#40;a^2 &#43; b&#41;/c$</span>.</p>
<ul>
<li><p>Note: <code>^</code> &#40;carat&#41; is the exponentiation operator.</p>
</li>
</ul>
</li>
</ul>
</div>
</div>mimetext/htmlrootassigneelast_run_timestampA}QS`̰persist_js_state·has_pluto_hook_features§cell_id$1416a80e-dbda-4185-8984-7f5de3c58f02depends_on_disabled_cells§runtime 	-published_object_keysdepends_on_skipped_cells§errored$21190213-dc6e-4206-b516-338d5922b30equeued¤logsrunning¦outputbody<div class="markdown"><h1 id="Tuple-Creation">Tuple Creation</h1>
<p>Like Python, Julia has Tuples. Tuples differ from arrays in two aspects:</p>
<ol>
<li><p>A Tuple is <strong>immutable</strong>. That means that once created the values cannot be changed.</p>
</li>
<li><p>A Tuple is <strong>one-dimensional</strong>.</p>
</li>
<li><p>A Tuple is <strong>non-allocating</strong>. Therefore, they have better performance that Arrays.</p>
</li>
</ol>
<h2 id="Tuple-Literals">Tuple Literals</h2>
<p>Literal tuples are create by using <code>&#40;&#41;</code> &#40;paratheses&#41; whose elements are separated by &#39;<code>,</code>&#39; &#40;commas&#41;. For example:</p>
<pre><code class="language-julia-repl">julia&gt; t &#61; &#40;1, 2., &quot;three&quot;&#41;
&#40;1, 2.0, &quot;three&quot;&#41;

julia&gt; typeof&#40;t&#41;
Tuple&#123;Int64, Float64, String&#125;</code></pre>
<h2 id="NamedTuples">NamedTuples</h2>
<p>Julia also has a named tuple type. They are basically identical to Tuples, except that the elements can have names or labels by preceeding the value with a character or string and an &#39;<code>&#61;</code>&#39; &#40;equal sign&#41;. For example:</p>
<pre><code class="language-julia-repl">julia&gt; n &#61; &#40;a&#61;1, b&#61;2, c&#61;&quot;three&quot;&#41;
&#40;a &#61; 1, b &#61; 2, c &#61; &quot;three&quot;&#41;</code></pre>
<p>There is also a syntatic variation the begins with &#39;<code>&#40;;</code>&#39; &#40;parenthesis - semi-colon&#41;.</p>
<pre><code class="language-julia-repl">julia&gt; n &#61; &#40;; a&#61;1, b&#61;2, c&#61;&quot;three&quot;&#41;
&#40;a &#61; 1, b &#61; 2, c &#61; &quot;three&quot;&#41;</code></pre>
<p>Tuples and NamedTuples can also be created using the <code>Tuple</code> and <code>NamedTuple</code> types. See the help documents for details.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA}QQ#persist_js_state·has_pluto_hook_features§cell_id$21190213-dc6e-4206-b516-338d5922b30edepends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$d5268417-62f9-4fa8-beac-c4d4b9007223queued¤logsrunning¦outputbody<div class="markdown"><h1 id="Broadcasting-&#40;-.-Operator&#41;">Broadcasting &#40; <code>.</code> Operator&#41;</h1>
<p>This is arguably the most important feature for clean, fast code using arrays or tuples.</p>
<h2 id="Arrays">Arrays</h2>
<p>What if you have a vector <code>A &#61; &#91;1, 2, 3&#93;</code> and you want to add 1 to every element? Or what if you want to multiply every element in an array by its corresponding element in another array?</p>
<p>The <code>.</code> operator is a prefix operator that modifies the behavior of other operators such as <code>&#43;</code> and <code>*</code>. It tells Julia to. perform an element-wise operation. The <code>.</code> operator is called the <strong>broadcast</strong> operator. As we will see in session 1-4, it applies to more than just arrays.</p>
<ol>
<li><p><code>A .&#43; 1</code> <span class="tex">$\rightarrow$</span> <code>&#91;2, 3, 4&#93;</code></p>
</li>
<li><p><code>A .* B</code> means element-by-element multiplication.</p>
</li>
</ol>
<h2 id="Tuples">Tuples</h2>
<p>The broadcast operator also applies to Tuples. For example:</p>
<pre><code class="language-julia-repl">julia&gt; &#40;1, 2, 3&#41; .&#43; &#40;4, 5, 6&#41;
&#40;5, 7, 9&#41;</code></pre>
</div>mimetext/htmlrootassigneelast_run_timestampA}QQ[upersist_js_state·has_pluto_hook_features§cell_id$d5268417-62f9-4fa8-beac-c4d4b9007223depends_on_disabled_cells§runtime >ĵpublished_object_keysdepends_on_skipped_cells§errored$346cb64d-3c89-44d1-9edb-06354152243aqueued¤logsrunning¦outputbody<div class="markdown"><h1 id="Matrix-Protocol">Matrix Protocol</h1>
<p>Julia&#39;s arrays behave differently from arrays in languages like Python, C, or Java. Julia&#39;s design follows the conventions of mathematics and linear algebra, which has two major consequences.</p>
<ol>
<li><p>1-Based Indexing</p>
<p>The first element of an array is at index 1.</p>
</li>
</ol>
<ol>
<li><p><code>my_vector&#91;1&#93;</code> is the first element.</p>
</li>
</ol>
<ol start="2">
<li><p><code>my_matrix&#91;1, 1&#93;</code> is the top-left element.</p>
</li>
</ol>
<p>Python and C use 0-based indexing &#40;where <code>my_array&#91;0&#93;</code> is the first element&#41;. This 1-based system may be more intuitive for mathematicians and scientists who are used to notation such as <span class="tex">$A_&#123;ij&#125;$</span>, where <span class="tex">$i$</span> and <span class="tex">$j$</span> start at 1.</p>
<ol start="2">
<li><p>Column-Major Order</p>
<p>This is one secret to Julia&#39;s performance. It describes how arrays are physically laid out in your computer&#39;s memory.</p>
</li>
</ol>
<ol>
<li><p>Row-major order: Elements of a row are grouped together in memory. The computer stores &#91;row1, row2, row3&#93; &#40;e.g., used by NumPy and C&#41;</p>
</li>
</ol>
<ol start="2">
<li><p>Column-major order: Elements of a column are grouped together. The computer stores &#91;col1, col2, col3&#93;. &#40;used by e.g., Julia, MATLAB, and FORTRAN&#41;</p>
</li>
</ol>
<p>Why does this matter? Accessing memory that is close together is typically much faster &#40;due to CPU caching&#41; than accessing memory that is spread out.</p>
<p>In Julia, this means that looping down a column, i.e., through the rows, is fast.</p>
<pre><code class="language-julia-repl">julia&gt; for j in 1:numCols
	for i in 1:numRows
		# Accessing memory sequentially is better, e.g.,
		A&#91;i, j&#93; ...
	end
end</code></pre>
<div class="admonition note"><p class="admonition-title">Note</p><p><code>#</code> character begins a single comment, i.e., the comment string is between the <code>#</code> character and the newline character.</p>
<p><code>#&#61;</code> and <code>&#61;#</code> is a string block that can span multiple lines.</p>
</div>
</div>mimetext/htmlrootassigneelast_run_timestampA}QPpersist_js_state·has_pluto_hook_features§cell_id$346cb64d-3c89-44d1-9edb-06354152243adepends_on_disabled_cells§runtime #published_object_keysdepends_on_skipped_cells§errored$e3b1c6c2-5631-42c0-9a1b-d5a5520466c8queued¤logsrunning¦outputbody<div class="markdown"><h2 id="1:-Array-Construction">1: Array Construction</h2>
<div class="admonition warning"><p class="admonition-title"></p><ul>
<li><p>Construct a Vector using an array literal with the values 1, 2, 3.</p>
</li>
<li><p>Construct a 3×3 matrix using an array literal with 1, 2, 3 in the first row.</p>
</li>
<li><p>Construct a 3×3 matrix using an array literal with 1, 2, 3 in the first column.</p>
</li>
<li><p>Construct a 3×3 matrix of interger zeros.</p>
<ul>
<li><p>Hint: Use <code>zeros&#40;&#41;</code>.</p>
</li>
</ul>
</li>
<li><p>Construct a 3×3 matrix of Float32 ones.</p>
</li>
<li><p>Construct a 3×3 matrix of UInt8 filled with the value 8.</p>
<ul>
<li><p>Hint: Use <code>fill&#40;&#41;</code>.</p>
</li>
</ul>
</li>
<li><p>Construct a 3×3×3 array of Float32 whose values are undefined.</p>
<ul>
<li><p>Hint: Use <code>Array&#40;&#41;</code> and <code>undef</code>.</p>
</li>
<li><p>Note: This array allocates memory, but does not initilize it, saving time.</p>
</li>
</ul>
</li>
</ul>
</div>
</div>mimetext/htmlrootassigneelast_run_timestampA}QRװpersist_js_state·has_pluto_hook_features§cell_id$e3b1c6c2-5631-42c0-9a1b-d5a5520466c8depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$ff17e921-4522-4ab3-8282-9d9aafecdbe9queued¤logsrunning¦outputbodyH<div class="markdown"><h2 id="3:-Broadcasting">3: Broadcasting</h2>
<div class="admonition warning"><p class="admonition-title"></p><ul>
<li><p>Construct a 1D vector <code>x</code> containing five evenly spaced points from 0 to <span class="tex">$\pi$</span>, inclusive.</p>
<ul>
<li><p>Hint: Use <code>range&#40;&#41;</code>.</p>
</li>
<li><p>Note: <code>π</code> is a built-in constant.</p>
</li>
</ul>
</li>
<li><p>Construct a 1D vector <code>y</code> containing five random values between 1 and 10.</p>
<ul>
<li><p>Hint: use <code>rand&#40;&#41;</code>.</p>
</li>
</ul>
</li>
<li><p>Multiply element-wise <code>x</code> and <code>y</code>.</p>
</li>
<li><p>Construct a third 1D vector <code>z</code> containing five values.</p>
</li>
<li><p>Evaluate the expression <span class="tex">$x &#43; y * z$</span></p>
</li>
</ul>
</div>
</div>mimetext/htmlrootassigneelast_run_timestampA}QR{persist_js_state·has_pluto_hook_features§cell_id$ff17e921-4522-4ab3-8282-9d9aafecdbe9depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$e022f21e-7f18-4690-99d4-0141403b3b38queued¤logsrunning¦outputbodye<div class="markdown"><h2 id="4:-Matrix-Math-vs.-Element-wise-Math">4: Matrix Math vs. Element-wise Math</h2>
<div class="admonition warning"><p class="admonition-title"></p><ul>
<li><p>Create two 2×2 matrices:</p>
<ul>
<li><p><code>X &#61; &#91;1 2; 3 4&#93;</code></p>
</li>
<li><p><code>Y &#61; &#91;2 0; 0 2&#93; # This is a scaling matrix.</code></p>
</li>
</ul>
</li>
<li><p>Perform matrix multiplication on <code>X</code> and <code>Y</code>.</p>
</li>
<li><p>Perform element-wise multiplication on <code>X</code> and <code>Y</code>.</p>
</li>
<li><p>Are the results the same?</p>
</li>
</ul>
</div>
</div>mimetext/htmlrootassigneelast_run_timestampA}QS2persist_js_state·has_pluto_hook_features§cell_id$e022f21e-7f18-4690-99d4-0141403b3b38depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$116911ed-cc32-41ea-a495-a3117815d669queued¤logsrunning¦outputbody$<div class="markdown"><pre><code class="language-julia-repl">julia&gt; A &#61; &#91;1 2; 3 4&#93;
2×2 Matrix&#123;Int64&#125;:
 1  2
 3  4

julia&gt; B &#61; &#91;5 6; 7 8&#93;
2×2 Matrix&#123;Int64&#125;:
 5  6
 7  8</code></pre>
<p>Element-wise multiplication</p>
<pre><code class="language-julia-repl">julia&gt; C &#61; A .* B
2×2 Matrix&#123;Int64&#125;:
  5  12
 21  32</code></pre>
<p>Matrix multiplication</p>
<pre><code class="language-julia-repl">julia&gt; D &#61; A * B
2×2 Matrix&#123;Int64&#125;:
 19  22
 43  50</code></pre>
</div>mimetext/htmlrootassigneelast_run_timestampA}QQ%persist_js_state·has_pluto_hook_features§cell_id$116911ed-cc32-41ea-a495-a3117815d669depends_on_disabled_cells§runtime 	published_object_keysdepends_on_skipped_cells§errored$29e28885-d969-4e27-b5d3-866eb25302abqueued¤logsrunning¦outputbody<div class="markdown"><h1 id="Summary">Summary</h1>
<div class="admonition note"><p class="admonition-title"></p><ul>
<li><p><code>&#91;...&#93;</code> is the syntax for a literal <code>Array</code> comprehension.</p>
</li>
<li><p><code>&#40;...&#41;</code> is the syntax for a literal <code>Tuple</code> comprehension.</p>
</li>
<li><p><code>&#40;...&#61;..., ...&#61;...&#41;</code> is the syntax for a literal <code>NamedTuple</code> comprehension.</p>
</li>
<li><p><code>.*</code> &#40;dot&#41;: broadcast operator, i.e., use for element-wide operations.</p>
</li>
<li><p><code>*</code> &#40;no dot&#41;: matix operator, i,e., use for matrix multiplication.</p>
</li>
</ul>
</div>
</div>mimetext/htmlrootassigneelast_run_timestampA}QRpersist_js_state·has_pluto_hook_features§cell_id$29e28885-d969-4e27-b5d3-866eb25302abdepends_on_disabled_cells§runtime 
Fmpublished_object_keysdepends_on_skipped_cells§errored$624bd571-c51e-4f52-848b-7cdefebbd42aqueued¤logsrunning¦outputbodyP<script>
	
// Load the library for consistent smooth scrolling
const {default: scrollIntoView} = await import("data:text/javascript;base64,dmFyIFE9ZT0+Im9iamVjdCI9PXR5cGVvZiBlJiZudWxsIT1lJiYxPT09ZS5ub2RlVHlwZSxVPShlLHQpPT4oIXR8fCJoaWRkZW4iIT09ZSkmJiJ2aXNpYmxlIiE9PWUmJiJjbGlwIiE9PWUsQT0oZSx0KT0+e2lmKGUuY2xpZW50SGVpZ2h0PGUuc2Nyb2xsSGVpZ2h0fHxlLmNsaWVudFdpZHRoPGUuc2Nyb2xsV2lkdGgpe2xldCBsPWdldENvbXB1dGVkU3R5bGUoZSxudWxsKTtyZXR1cm4gVShsLm92ZXJmbG93WSx0KXx8VShsLm92ZXJmbG93WCx0KXx8KGU9PntsZXQgdD0oZT0+e2lmKCFlLm93bmVyRG9jdW1lbnR8fCFlLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXcpcmV0dXJuIG51bGw7dHJ5e3JldHVybiBlLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXcuZnJhbWVFbGVtZW50fWNhdGNoe3JldHVybiBudWxsfX0pKGUpO3JldHVybiEhdCYmKHQuY2xpZW50SGVpZ2h0PGUuc2Nyb2xsSGVpZ2h0fHx0LmNsaWVudFdpZHRoPGUuc2Nyb2xsV2lkdGgpfSkoZSl9cmV0dXJuITF9LFg9KGUsdCxsLG8sbixyLGkscyk9PnI8ZSYmaT50fHxyPmUmJmk8dD8wOnI8PWUmJnM8PWx8fGk+PXQmJnM+PWw/ci1lLW86aT50JiZzPGx8fHI8ZSYmcz5sP2ktdCtuOjAsJD1lPT5lLnBhcmVudEVsZW1lbnQ/PyhlLmdldFJvb3ROb2RlKCkuaG9zdHx8bnVsbCksdHQ9KGUsdCk9Pnt2YXIgbCxvLG4scjtpZih0eXBlb2YgZG9jdW1lbnQ+InUiKXJldHVybltdO2xldHtzY3JvbGxNb2RlOmksYmxvY2s6cyxpbmxpbmU6YSxib3VuZGFyeTpoLHNraXBPdmVyZmxvd0hpZGRlbkVsZW1lbnRzOnV9PXQsZz0iZnVuY3Rpb24iPT10eXBlb2YgaD9oOmU9PmUhPT1oO2lmKCFRKGUpKXRocm93IFR5cGVFcnJvcigiSW52YWxpZCB0YXJnZXQiKTtsZXQgdj1kb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50fHxkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsbT1bXSx3PWU7Zm9yKDtRKHcpJiZnKHcpOyl7aWYoKHc9JCh3KSk9PT12KXttLnB1c2godyk7YnJlYWt9bnVsbCE9dyYmdz09PWRvY3VtZW50LmJvZHkmJkEodykmJiFBKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCl8fG51bGwhPXcmJkEodyx1KSYmbS5wdXNoKHcpfWxldCBXPW51bGwhPShvPW51bGw9PShsPXdpbmRvdy52aXN1YWxWaWV3cG9ydCk/dm9pZCAwOmwud2lkdGgpP286aW5uZXJXaWR0aCxIPW51bGwhPShyPW51bGw9PShuPXdpbmRvdy52aXN1YWxWaWV3cG9ydCk/dm9pZCAwOm4uaGVpZ2h0KT9yOmlubmVySGVpZ2h0LHtzY3JvbGxYOl8sc2Nyb2xsWTp4fT13aW5kb3cse2hlaWdodDpFLHdpZHRoOlQsdG9wOk4scmlnaHQ6TCxib3R0b206WSxsZWZ0OkN9PWUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksUj0ic3RhcnQiPT09c3x8Im5lYXJlc3QiPT09cz9OOiJlbmQiPT09cz9ZOk4rRS8yLFY9ImNlbnRlciI9PT1hP0MrVC8yOiJlbmQiPT09YT9MOkMsQj1bXTtmb3IobGV0IEQ9MDtEPG0ubGVuZ3RoO0QrKyl7bGV0IE89bVtEXSx7aGVpZ2h0Omosd2lkdGg6SSx0b3A6UyxyaWdodDpxLGJvdHRvbTp6LGxlZnQ6Rn09Ty5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtpZigiaWYtbmVlZGVkIj09PWkmJk4+PTAmJkM+PTAmJlk8PUgmJkw8PVcmJk4+PVMmJlk8PXomJkM+PUYmJkw8PXEpYnJlYWs7bGV0IEc9Z2V0Q29tcHV0ZWRTdHlsZShPKSxKPXBhcnNlSW50KEcuYm9yZGVyTGVmdFdpZHRoLDEwKSxLPXBhcnNlSW50KEcuYm9yZGVyVG9wV2lkdGgsMTApLFA9cGFyc2VJbnQoRy5ib3JkZXJSaWdodFdpZHRoLDEwKSxaPXBhcnNlSW50KEcuYm9yZGVyQm90dG9tV2lkdGgsMTApLGVlPTAsZXQ9MCxlbD0ib2Zmc2V0V2lkdGgiaW4gTz9PLm9mZnNldFdpZHRoLU8uY2xpZW50V2lkdGgtSi1QOjAsZW89Im9mZnNldEhlaWdodCJpbiBPP08ub2Zmc2V0SGVpZ2h0LU8uY2xpZW50SGVpZ2h0LUstWjowLGVuPSJvZmZzZXRXaWR0aCJpbiBPPzA9PT1PLm9mZnNldFdpZHRoPzA6SS9PLm9mZnNldFdpZHRoOjAsZXI9Im9mZnNldEhlaWdodCJpbiBPPzA9PT1PLm9mZnNldEhlaWdodD8wOmovTy5vZmZzZXRIZWlnaHQ6MDtpZih2PT09TyllZT0ic3RhcnQiPT09cz9SOiJlbmQiPT09cz9SLUg6Im5lYXJlc3QiPT09cz9YKHgseCtILEgsSyxaLHgrUix4K1IrRSxFKTpSLUgvMixldD0ic3RhcnQiPT09YT9WOiJjZW50ZXIiPT09YT9WLVcvMjoiZW5kIj09PWE/Vi1XOlgoXyxfK1csVyxKLFAsXytWLF8rVitULFQpLGVlPU1hdGgubWF4KDAsZWUreCksZXQ9TWF0aC5tYXgoMCxldCtfKTtlbHNle2VlPSJzdGFydCI9PT1zP1ItUy1LOiJlbmQiPT09cz9SLXorWitlbzoibmVhcmVzdCI9PT1zP1goUyx6LGosSyxaK2VvLFIsUitFLEUpOlItKFMrai8yKStlby8yLGV0PSJzdGFydCI9PT1hP1YtRi1KOiJjZW50ZXIiPT09YT9WLShGK0kvMikrZWwvMjoiZW5kIj09PWE/Vi1xK1ArZWw6WChGLHEsSSxKLFArZWwsVixWK1QsVCk7bGV0e3Njcm9sbExlZnQ6ZWksc2Nyb2xsVG9wOmVkfT1PO2VlPU1hdGgubWF4KDAsTWF0aC5taW4oZWQrZWUvZXIsTy5zY3JvbGxIZWlnaHQtai9lcitlbykpLGV0PU1hdGgubWF4KDAsTWF0aC5taW4oZWkrZXQvZW4sTy5zY3JvbGxXaWR0aC1JL2VuK2VsKSksUis9ZWQtZWUsVis9ZWktZXR9Qi5wdXNoKHtlbDpPLHRvcDplZSxsZWZ0OmV0fSl9cmV0dXJuIEJ9LGY9ZT0+e3ZhciB0O3JldHVybiExPT09ZT97YmxvY2s6ImVuZCIsaW5saW5lOiJuZWFyZXN0In06KHQ9ZSk9PT1PYmplY3QodCkmJjAhPT1PYmplY3Qua2V5cyh0KS5sZW5ndGg/ZTp7YmxvY2s6InN0YXJ0IixpbmxpbmU6Im5lYXJlc3QifX07ZnVuY3Rpb24gYyhlLHQpe3ZhciBsO2lmKCFlLmlzQ29ubmVjdGVkfHwhKGU9PntsZXQgdD1lO2Zvcig7dCYmdC5wYXJlbnROb2RlOyl7aWYodC5wYXJlbnROb2RlPT09ZG9jdW1lbnQpcmV0dXJuITA7dD10LnBhcmVudE5vZGUgaW5zdGFuY2VvZiBTaGFkb3dSb290P3QucGFyZW50Tm9kZS5ob3N0OnQucGFyZW50Tm9kZX1yZXR1cm4hMX0pKGUpKXJldHVybjtpZigib2JqZWN0Ij09dHlwZW9mKGw9dCkmJiJmdW5jdGlvbiI9PXR5cGVvZiBsLmJlaGF2aW9yKXJldHVybiB0LmJlaGF2aW9yKHR0KGUsdCkpO2xldCBvPSJib29sZWFuIj09dHlwZW9mIHR8fG51bGw9PXQ/dm9pZCAwOnQuYmVoYXZpb3I7Zm9yKGxldHtlbDpuLHRvcDpyLGxlZnQ6aX1vZiB0dChlLGYodCkpKW4uc2Nyb2xsKHt0b3A6cixsZWZ0OmksYmVoYXZpb3I6b30pfXZhciBkLHA9KCk9PihkfHwoZD0icGVyZm9ybWFuY2UiaW4gd2luZG93P3BlcmZvcm1hbmNlLm5vdy5iaW5kKHBlcmZvcm1hbmNlKTpEYXRlLm5vdyksZCgpKTtmdW5jdGlvbiBiKGUpe2xldCB0PU1hdGgubWluKChwKCktZS5zdGFydFRpbWUpL2UuZHVyYXRpb24sMSksbD1lLmVhc2UodCksbz1lLnN0YXJ0WCsoZS54LWUuc3RhcnRYKSpsLG49ZS5zdGFydFkrKGUueS1lLnN0YXJ0WSkqbDtlLm1ldGhvZChvLG4sdCxsKSxvIT09ZS54fHxuIT09ZS55P3JlcXVlc3RBbmltYXRpb25GcmFtZSgoKT0+YihlKSk6ZS5jYigpfWZ1bmN0aW9uIHkoZSx0LGwpe2xldCBvPWFyZ3VtZW50cy5sZW5ndGg+MyYmdm9pZCAwIT09YXJndW1lbnRzWzNdP2FyZ3VtZW50c1szXTo2MDAsbj1hcmd1bWVudHMubGVuZ3RoPjQmJnZvaWQgMCE9PWFyZ3VtZW50c1s0XT9hcmd1bWVudHNbNF06ZT0+MSstLWUqZSplKmUqZSxyPWFyZ3VtZW50cy5sZW5ndGg+NT9hcmd1bWVudHNbNV06dm9pZCAwLGk9YXJndW1lbnRzLmxlbmd0aD42P2FyZ3VtZW50c1s2XTp2b2lkIDAscz1lLnNjcm9sbExlZnQsYT1lLnNjcm9sbFRvcDtiKHtzY3JvbGxhYmxlOmUsbWV0aG9kKHQsbCxvLG4pe2xldCByPU1hdGguY2VpbCh0KSxzPU1hdGguY2VpbChsKTtlLnNjcm9sbExlZnQ9cixlLnNjcm9sbFRvcD1zLGk/Lih7dGFyZ2V0OmUsZWxhcHNlZDpvLHZhbHVlOm4sbGVmdDpyLHRvcDpzfSl9LHN0YXJ0VGltZTpwKCksc3RhcnRYOnMsc3RhcnRZOmEseDp0LHk6bCxkdXJhdGlvbjpvLGVhc2U6bixjYjpyfSl9dmFyIE09ZT0+ZSYmIWUuYmVoYXZpb3J8fCJzbW9vdGgiPT09ZS5iZWhhdmlvcixrPWZ1bmN0aW9uKGUsdCl7bGV0IGw9dHx8e307cmV0dXJuIE0obCk/YyhlLHtibG9jazpsLmJsb2NrLGlubGluZTpsLmlubGluZSxzY3JvbGxNb2RlOmwuc2Nyb2xsTW9kZSxib3VuZGFyeTpsLmJvdW5kYXJ5LHNraXBPdmVyZmxvd0hpZGRlbkVsZW1lbnRzOmwuc2tpcE92ZXJmbG93SGlkZGVuRWxlbWVudHMsYmVoYXZpb3I6ZT0+UHJvbWlzZS5hbGwoZS5yZWR1Y2UoKGUsdCk9PntsZXR7ZWw6byxsZWZ0Om4sdG9wOnJ9PXQsaT1vLnNjcm9sbExlZnQscz1vLnNjcm9sbFRvcDtyZXR1cm4gaT09PW4mJnM9PT1yP2U6Wy4uLmUsbmV3IFByb21pc2UoZT0+eShvLG4scixsLmR1cmF0aW9uLGwuZWFzZSwoKT0+ZSh7ZWw6byxsZWZ0OltpLG5dLHRvcDpbcyxyXX0pLGwub25TY3JvbGxDaGFuZ2UpKV19LFtdKSl9KTpQcm9taXNlLnJlc29sdmUoYyhlLHQpKX07ZXhwb3J0e2sgYXMgZGVmYXVsdH07")

const indent = true
const aside = true
const title_text = "1-2: Arrays 1"
const include_definitions = false


const tocNode = html`<nav class="plutoui-toc">
	<header>
	 <span class="toc-toggle open-toc"></span>
	 <span class="toc-toggle closed-toc"></span>
	 ${title_text}
	</header>
	<section></section>
</nav>`

tocNode.classList.toggle("aside", aside)
tocNode.classList.toggle("indent", indent)


const getParentCell = el => el.closest("pluto-cell")

const getHeaders = () => {
	const depth = Math.max(1, Math.min(6, 4)) // should be in range 1:6
	const range = Array.from({length: depth}, (x, i) => i+1) // [1, ..., depth]
	
	const selector = [
		...(include_definitions ? [
			`pluto-notebook pluto-cell .pluto-docs-binding`, 
			`pluto-notebook pluto-cell assignee:not(:empty)`, 
		] : []),
		...range.map(i => `pluto-notebook pluto-cell h${i}`)
	].join(",")
	return Array.from(document.querySelectorAll(selector)).filter(el => 
		// exclude headers inside of a pluto-docs-binding block
		!(el.nodeName.startsWith("H") && el.closest(".pluto-docs-binding")) && !el.classList.contains("no-toc")
	)
}


const document_click_handler = (event) => {
	const path = (event.path || event.composedPath())
	const toc = path.find(elem => elem?.classList?.contains?.("toc-toggle"))
	if (toc) {
		event.stopImmediatePropagation()
		toc.closest(".plutoui-toc").classList.toggle("hide")
	}
}

document.addEventListener("click", document_click_handler)


const header_to_index_entry_map = new Map()
const currently_highlighted_set = new Set()

const last_toc_element_click_time = { current: 0 }

const intersection_callback = (ixs) => {
	let on_top = ixs.filter(ix => ix.intersectionRatio > 0 && ix.intersectionRect.y < ix.rootBounds.height / 2)
	if(on_top.length > 0){
		currently_highlighted_set.forEach(a => a.classList.remove("in-view"))
		currently_highlighted_set.clear()
		on_top.slice(0,1).forEach(i => {
			let div = header_to_index_entry_map.get(i.target)
			div.classList.add("in-view")
			currently_highlighted_set.add(div)
			
			/// scroll into view
			/*
			const toc_height = tocNode.offsetHeight
			const div_pos = div.offsetTop
			const div_height = div.offsetHeight
			const current_scroll = tocNode.scrollTop
			const header_height = tocNode.querySelector("header").offsetHeight
			
			const scroll_to_top = div_pos - header_height
			const scroll_to_bottom = div_pos + div_height - toc_height
			
			// if we set a scrollTop, then the browser will stop any currently ongoing smoothscroll animation. So let's only do this if you are not currently in a smoothscroll.
			if(Date.now() - last_toc_element_click_time.current >= 2000)
				if(current_scroll < scroll_to_bottom){
					tocNode.scrollTop = scroll_to_bottom
				} else if(current_scroll > scroll_to_top){
					tocNode.scrollTop = scroll_to_top
				}
			*/
		})
	}
}
let intersection_observer_1 = new IntersectionObserver(intersection_callback, {
	root: null, // i.e. the viewport
  	threshold: 1,
	rootMargin: "-15px", // slightly smaller than the viewport
	// delay: 100,
})
let intersection_observer_2 = new IntersectionObserver(intersection_callback, {
	root: null, // i.e. the viewport
  	threshold: 1,
	rootMargin: "15px", // slightly larger than the viewport
	// delay: 100,
})

const render = (elements) => {
	header_to_index_entry_map.clear()
	currently_highlighted_set.clear()
	intersection_observer_1.disconnect()
	intersection_observer_2.disconnect()

		let last_level = `H1`
	return html`${elements.map(h => {
	const parent_cell = getParentCell(h)

		let [className, title_el] = h.matches(`.pluto-docs-binding`) ? ["pluto-docs-binding-el", h.firstElementChild] : [h.nodeName, h]

	const id = title_el.matches("assignee") ?
		title_el.innerText.replace(/^const /, "") :
		title_el.id ?
		title_el.id :
		parent_cell.id
	
	const inner_html = title_el.innerHTML
		
	const a = html`<a 
		class="${className}" 
		title="${title_el.innerText}"
		href="#${id}"
	>${inner_html}</a>`
	/* a.onmouseover=()=>{
		parent_cell.firstElementChild.classList.add(
			'highlight-pluto-cell-shoulder'
		)
	}
	a.onmouseout=() => {
		parent_cell.firstElementChild.classList.remove(
			'highlight-pluto-cell-shoulder'
		)
	} */
		
		
	a.onclick=(e) => {
		e.preventDefault();
		history.replaceState(null, null, a.href)
		last_toc_element_click_time.current = Date.now()
		scrollIntoView(h, {
			behavior: 'smooth', 
			block: 'start',
		}).then(() => 
			// sometimes it doesn't scroll to the right place
			// solution: try a second time!
			scrollIntoView(h, {
				behavior: 'smooth', 
				block: 'start',
			})
	   )
	}
	   
	// Remove any `id` attributes recursively, because they may interfere with linking-to-id using `#`
	const removeIdAttributes = (el) => {
		if (el && el.nodeType === 1) { // Element node
			if (el.hasAttribute?.("id")) el.removeAttribute?.("id")
			el.childNodes.forEach(removeIdAttributes)
		}
	}
	removeIdAttributes(a)

	// Remove Click-To-Copy-Header-ID feature
	a.querySelectorAll("pluto-header-id-copy-wrapper").forEach(el => el.remove())

	const row =  html`<div class="toc-row ${className} after-${last_level}">${a}</div>`
		intersection_observer_1.observe(title_el)
		intersection_observer_2.observe(title_el)
		header_to_index_entry_map.set(title_el, row)

	if(className.startsWith("H"))
		last_level = className
		
	return row
})}`
}

const invalidated = { current: false }

const updateCallback = () => {
	if (!invalidated.current) {
		tocNode.querySelector("section").replaceWith(
			html`<section>${render(getHeaders())}</section>`
		)
	}
}
updateCallback()
setTimeout(updateCallback, 100)
setTimeout(updateCallback, 1000)
setTimeout(updateCallback, 5000)

const notebook = document.querySelector("pluto-notebook")


// We have a mutationobserver for each cell:
const mut_observers = {
	current: [],
}

const createCellObservers = () => {
	mut_observers.current.forEach((o) => o.disconnect())
	mut_observers.current = Array.from(notebook.querySelectorAll("pluto-cell")).map(el => {
		const o = new MutationObserver(updateCallback)
		o.observe(el, {attributeFilter: ["class"]})
		return o
	})
}
createCellObservers()

// And one for the notebook's child list, which updates our cell observers:
const notebookObserver = new MutationObserver(() => {
	updateCallback()
	createCellObservers()
})
notebookObserver.observe(notebook, {childList: true})

// And finally, an observer for the document.body classList, to make sure that the toc also works when it is loaded during notebook initialization
const bodyClassObserver = new MutationObserver(updateCallback)
bodyClassObserver.observe(document.body, {attributeFilter: ["class"]})

// Hide/show the ToC when the screen gets small
let match_listener = () => {
	const small = (tocNode.closest("pluto-editor") ?? document.body).scrollWidth < 1000
	tocNode.classList.toggle("smallscreen", small)
	tocNode.classList.toggle("hide", small)
}
for(let s of [1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000]) {
	let m = matchMedia(`(max-width: ${s}px)`)
	m.addListener(match_listener)
	invalidation.then(() => m.removeListener(match_listener))
}
match_listener()

invalidation.then(() => {
	invalidated.current = true
	intersection_observer_1.disconnect()
	intersection_observer_2.disconnect()
	notebookObserver.disconnect()
	bodyClassObserver.disconnect()
	mut_observers.current.forEach((o) => o.disconnect())
	document.removeEventListener("click", document_click_handler)
})

return tocNode
</script>
<style>
@media not print {

.plutoui-toc {
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Cantarell, "Apple Color Emoji",
		"Segoe UI Emoji", "Segoe UI Symbol", system-ui, sans-serif;
	--main-bg-color: #fafafa;
	--pluto-output-color: hsl(0, 0%, 36%);
	--pluto-output-h-color: hsl(0, 0%, 21%);
	--sidebar-li-active-bg: rgb(235, 235, 235);
	--icon-filter: unset;
}

@media (prefers-color-scheme: dark) {
	.plutoui-toc {
		--main-bg-color: #303030;
		--pluto-output-color: hsl(0, 0%, 90%);
		--pluto-output-h-color: hsl(0, 0%, 97%);
		--sidebar-li-active-bg: rgb(82, 82, 82);
		--icon-filter: invert(1);
	}
}

.plutoui-toc.aside {
	color: var(--pluto-output-color);
	position: fixed;
	right: 1rem;
	top: 5rem;
	width: min(80vw, 300px);
	padding: 0.5rem;
	padding-top: 0em;
	/* border: 3px solid rgba(0, 0, 0, 0.15); */
	border-radius: 10px;
	max-height: calc(100vh - 5rem - 90px);
	overflow: auto;
	z-index: 40;
	background-color: var(--main-bg-color);
	transition: transform 300ms cubic-bezier(0.18, 0.89, 0.45, 1.12);
}

.plutoui-toc.smallscreen:not(.hide) {
	box-shadow: 0 0 11px 0px #00000010;
}

.plutoui-toc.aside.hide {
	transform: translateX(calc(100% - 28px));
	color: transparent;
}
.plutoui-toc.aside.hide section {
	display: none;
}
.plutoui-toc.aside.hide header {
	margin-bottom: 0em;
	padding-bottom: 0em;
	border-bottom: none;
}
}  /* End of Media print query */
.plutoui-toc.aside.hide .open-toc,
.plutoui-toc.aside:not(.hide) .closed-toc,
.plutoui-toc:not(.aside) .closed-toc {
	display: none;
}

@media (prefers-reduced-motion) {
  .plutoui-toc.aside {
	transition-duration: 0s;
  }
}

.toc-toggle {
	cursor: pointer;
    padding: 1em;
    margin: -1em;
    margin-right: -0.7em;
    line-height: 1em;
    display: flex;
}

.toc-toggle::before {
    content: "";
    display: inline-block;
    height: 1em;
    width: 1em;
    background-image: url("https://cdn.jsdelivr.net/gh/ionic-team/ionicons@5.5.1/src/svg/list-outline.svg");
	/* generated using https://dopiaza.org/tools/datauri/index.php */
    background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiI+PHRpdGxlPmlvbmljb25zLXY1LW88L3RpdGxlPjxsaW5lIHgxPSIxNjAiIHkxPSIxNDQiIHgyPSI0NDgiIHkyPSIxNDQiIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOiMwMDA7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDozMnB4Ii8+PGxpbmUgeDE9IjE2MCIgeTE9IjI1NiIgeDI9IjQ0OCIgeTI9IjI1NiIgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6IzAwMDtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLXdpZHRoOjMycHgiLz48bGluZSB4MT0iMTYwIiB5MT0iMzY4IiB4Mj0iNDQ4IiB5Mj0iMzY4IiBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTojMDAwO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6MzJweCIvPjxjaXJjbGUgY3g9IjgwIiBjeT0iMTQ0IiByPSIxNiIgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6IzAwMDtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLXdpZHRoOjMycHgiLz48Y2lyY2xlIGN4PSI4MCIgY3k9IjI1NiIgcj0iMTYiIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOiMwMDA7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDozMnB4Ii8+PGNpcmNsZSBjeD0iODAiIGN5PSIzNjgiIHI9IjE2IiBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTojMDAwO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6MzJweCIvPjwvc3ZnPg==");
    background-size: 1em;
	filter: var(--icon-filter);
}

.aside .toc-toggle.open-toc:hover::before {
    background-image: url("https://cdn.jsdelivr.net/gh/ionic-team/ionicons@5.5.1/src/svg/arrow-forward-outline.svg");
	/* generated using https://dopiaza.org/tools/datauri/index.php */
    background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiI+PHRpdGxlPmlvbmljb25zLXY1LWE8L3RpdGxlPjxwb2x5bGluZSBwb2ludHM9IjI2OCAxMTIgNDEyIDI1NiAyNjggNDAwIiBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTojMDAwO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6NDhweCIvPjxsaW5lIHgxPSIzOTIiIHkxPSIyNTYiIHgyPSIxMDAiIHkyPSIyNTYiIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOiMwMDA7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDo0OHB4Ii8+PC9zdmc+");
}
.aside .toc-toggle.closed-toc:hover::before {
    background-image: url("https://cdn.jsdelivr.net/gh/ionic-team/ionicons@5.5.1/src/svg/arrow-back-outline.svg");
	/* generated using https://dopiaza.org/tools/datauri/index.php */
    background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiI+PHRpdGxlPmlvbmljb25zLXY1LWE8L3RpdGxlPjxwb2x5bGluZSBwb2ludHM9IjI0NCA0MDAgMTAwIDI1NiAyNDQgMTEyIiBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTojMDAwO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6NDhweCIvPjxsaW5lIHgxPSIxMjAiIHkxPSIyNTYiIHgyPSI0MTIiIHkyPSIyNTYiIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOiMwMDA7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDo0OHB4Ii8+PC9zdmc+");
}



.plutoui-toc header {
	display: flex;
	align-items: center;
	gap: .3em;
	font-size: 1.5em;
	/* margin-top: -0.1em; */
	margin-bottom: 0.4em;
	padding: 0.5rem;
	margin-left: 0;
	margin-right: 0;
	font-weight: bold;
	/* border-bottom: 2px solid rgba(0, 0, 0, 0.15); */
	position: sticky;
	top: 0px;
	background: var(--main-bg-color);
	z-index: 41;
}
.plutoui-toc.aside header {
	padding-left: 0;
	padding-right: 0;
}

.plutoui-toc section .toc-row {
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	padding: .1em;
	border-radius: .2em;
}

.plutoui-toc section .toc-row.H1 {
	margin-top: 1em;
}


.plutoui-toc.aside section .toc-row.in-view {
	background: var(--sidebar-li-active-bg);
}


	
.highlight-pluto-cell-shoulder {
	background: rgba(0, 0, 0, 0.05);
	background-clip: padding-box;
}

.plutoui-toc section a {
	text-decoration: none;
	font-weight: normal;
	color: var(--pluto-output-color);
}
.plutoui-toc section a:hover {
	color: var(--pluto-output-h-color);
}

.plutoui-toc.indent section a.H1 {
	font-weight: 700;
	line-height: 1em;
}

.plutoui-toc.indent section .after-H2 a { padding-left: 10px; }
.plutoui-toc.indent section .after-H3 a { padding-left: 20px; }
.plutoui-toc.indent section .after-H4 a { padding-left: 30px; }
.plutoui-toc.indent section .after-H5 a { padding-left: 40px; }
.plutoui-toc.indent section .after-H6 a { padding-left: 50px; }

.plutoui-toc.indent section a.H1 { padding-left: 0px; }
.plutoui-toc.indent section a.H2 { padding-left: 10px; }
.plutoui-toc.indent section a.H3 { padding-left: 20px; }
.plutoui-toc.indent section a.H4 { padding-left: 30px; }
.plutoui-toc.indent section a.H5 { padding-left: 40px; }
.plutoui-toc.indent section a.H6 { padding-left: 50px; }


.plutoui-toc.indent section a.pluto-docs-binding-el,
.plutoui-toc.indent section a.ASSIGNEE
	{
	font-family: JuliaMono, monospace;
	font-size: .8em;
	/* background: black; */
	font-weight: 700;
    font-style: italic;
	color: var(--cm-var-color); /* this is stealing a variable from Pluto, but it's fine if that doesnt work */
}
.plutoui-toc.indent section a.pluto-docs-binding-el::before,
.plutoui-toc.indent section a.ASSIGNEE::before
	{
	content: "> ";
	opacity: .3;
}
</style>
mimetext/htmlrootassigneelast_run_timestampA}Qlcpersist_js_state·has_pluto_hook_features§cell_id$624bd571-c51e-4f52-848b-7cdefebbd42adepends_on_disabled_cells§runtime~published_object_keysdepends_on_skipped_cells§errored$e984391b-0c01-4dc8-85aa-3593027e8530queued¤logsrunning¦outputbodyٞ<div class="markdown"><div class="admonition note"><p class="admonition-title">1-2: Arrays 1</p><p><strong>Last Updated: 2 May 2026</strong></p>
</div>
</div>mimetext/htmlrootassigneelast_run_timestampA}QٸApersist_js_state·has_pluto_hook_features§cell_id$e984391b-0c01-4dc8-85aa-3593027e8530depends_on_disabled_cells§runtimeVepublished_object_keysdepends_on_skipped_cells§errored$11832b60-4906-4d22-960b-0b16b6634011queued¤logsrunning¦outputbody<div class="markdown"><h1 id="Array-Creation">Array Creation</h1>
<h2 id="Functions">Functions</h2>
<p>You can create arrays with functions like <code>zeros&#40;2, 3&#41;</code> or <code>rand&#40;3, 3&#41;</code>, where the integers in parentheses specify the dimensions.</p>
<h2 id="Array-Literals">Array Literals</h2>
<p>For literal arrays, we use <code>&#91;&#93;</code> with two simple rules:</p>
<ol>
<li><p>Commas &#40;<code>,</code>&#41; signify a 1D column Vector.</p>
</li>
<li><p>Spaces &#40; &#41; signify a 1D row Vector or a 1×N Matrix.</p>
</li>
</ol>
<pre><code class="language-julia-repl">julia&gt; x &#61; &#91;1., 2., 3.&#93;
3-element Vector&#123;Float64&#125;:
 1.0
 2.0
 3.0

julia&gt; y &#61; &#91;1. 2. 3.&#93;
1×3 Matrix&#123;Float64&#125;:
 1.0  2.0  3.0</code></pre>
<h2 id="Semicolon-Syntax">Semicolon Syntax</h2>
<p>Semicolons &#40;<code>;</code>&#41; separate rows.</p>
<p>The four following examples show array creation:</p>
<p>1: A 1D Vector &#40;using commas&#41; produces a 3-element Vector&#123;Int64&#125;:</p>
<pre><code class="language-julia-repl">julia&gt; v &#61; &#91;1, 2, 3&#93;
3-element Vector&#123;Int64&#125;:
 1
 2
 3</code></pre>
<p>2: A 2D Matrix &#40;using spaces for columns and semicolons for rows&#41; produces a 2×3 Matrix&#123;Int64&#125;:</p>
<pre><code class="language-julia-repl">julia&gt; m &#61; &#91;1 2 3; 4 5 6&#93;
2×3 Matrix&#123;Int64&#125;:
 1  2  3
 4  5  6</code></pre>
<p>A 1x3 Row Vector &#40;Matrix&#41; produces a 1×3 Matrix&#123;Int64&#125;:</p>
<pre><code class="language-julia-repl">julia&gt; row_vec &#61; &#91;1 2 3&#93;
1×3 Matrix&#123;Int64&#125;:
 1  2  3</code></pre>
<p>A 3x1 Column Vector &#40;Matrix&#41; produces a 3×1 Matrix&#123;Int64&#125;:</p>
<pre><code class="language-julia-repl">julia&gt; col_vec &#61; &#91;1; 2; 3&#93;
3-element Vector&#123;Int64&#125;:
 1
 2
 3</code></pre>
<div class="admonition note"><p class="admonition-title"></p><p><code>&#91;1, 2, 3&#93;</code>, with commas, gives a 1D Vector, while <code>&#91;1; 2; 3&#93;</code>, with semicolons, gives a 2D, 3×1 Matrix. The 1D Vector is &quot;dimensionless&quot; and often acts like a column vector in math operations, which is very convenient.</p>
</div>
<h2 id="Array-Elements">Array Elements</h2>
<p>Array elements do not need to be homogeneous. They can be heterogeneous, meaning that they can have any type. For example:</p>
<pre><code class="language-julia-repl">julia&gt; a &#61; &#91;1, 2f0, &quot;three&quot;, :four, nothing, missing&#93;
4-element Vector&#123;Any&#125;:
 1
 2.0f0
  &quot;three&quot;
  :four
  nothing
  missing</code></pre>
<div class="admonition note"><p class="admonition-title">Note</p><p>The <code>nothing</code> value is of type <code>Nothing</code> and is synonymous with Python&#39;s <code>none</code> object. The <code>missing</code> value is of type <code>Missing</code> and means that the value is missing. Statistical functions will ignore the <code>missing</code> value during computations, unlike the <code>nothing</code> value, so the results will be statistically correct.</p>
</div>
</div>mimetext/htmlrootassigneelast_run_timestampA}QPzpersist_js_state·has_pluto_hook_features§cell_id$11832b60-4906-4d22-960b-0b16b6634011depends_on_disabled_cells§runtime ڵpublished_object_keysdepends_on_skipped_cells§errored$30d5652d-605d-4119-b7e8-9cb8b93ce4a3queued¤logsrunning¦outputbodyv<div class="markdown"><h2 id="2:-Tuples-and-NamedTuples">2: Tuples and NamedTuples</h2>
<div class="admonition warning"><p class="admonition-title"></p><ul>
<li><p>Construct a Tuple literal <code>x</code> of three integers.</p>
</li>
<li><p>Construct a Tuple literal <code>y</code> of three floats.</p>
</li>
<li><p>Multiply <code>x</code> times <code>y</code>.</p>
</li>
<li><p>Construct a Tuple literal containing an integer, a float, and a string.</p>
</li>
<li><p>Construct a NamedTuple literal with labels <code>a</code>, <code>b</code>, and <code>c</code> and integer, float, and string values.</p>
</li>
</ul>
</div>
</div>mimetext/htmlrootassigneelast_run_timestampA}QRpersist_js_state·has_pluto_hook_features§cell_id$30d5652d-605d-4119-b7e8-9cb8b93ce4a3depends_on_disabled_cells§runtime 
õpublished_object_keysdepends_on_skipped_cells§errored$2675d602-810c-4320-971c-902c3327a5cbqueued¤logsrunning¦outputbody<div class="markdown"><h1 id="Multidimensional-Arrays">Multidimensional Arrays</h1>
<p>In Julia, an array is a collection of objects stored in a multi-dimensional grid.</p>
<ol>
<li><p>A 1D array is a Vector, i.e., as a single list or column of numbers.</p>
</li>
<li><p>A 2D array is a Matrix, i.e., rows and columns.</p>
</li>
<li><p>A 3D array is a cube of numbers, but of course one can keep going to 4D, 5D, or any number of dimensions.</p>
</li>
</ol>
<p>We interact with these using square brackets <code>&#91;&#93;</code> for indexing, e.g., <code>A&#91;2&#93;</code> gets the second element of a vector. <code>M&#91;2, 3&#93;</code> gets the element at the second row, third column of a matrix.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA}QOpersist_js_state·has_pluto_hook_features§cell_id$2675d602-810c-4320-971c-902c3327a5cbdepends_on_disabled_cells§runtime כpublished_object_keysdepends_on_skipped_cells§errored$8a5d4ccf-a3b2-4373-822d-dbf5254bf4b0queued¤logsrunning¦outputbody
4<div class="markdown"><h1 id="Array-Fusion">Array Fusion</h1>
<p>This is where the magic happens and the power of Juila. What happens if you chain multiple &quot;dotted&quot; operations?</p>
<pre><code class="language-julia-repl">julia&gt; A &#61; rand&#40;1000&#41;
julia&gt; B &#61; rand&#40;1000&#41;
julia&gt; C &#61; rand&#40;1000&#41;
julia&gt; D &#61; A .* B .&#43; C</code></pre>
<p>Let&#39;s compare how Python &#40;sp., Numpy&#41; and Julia compare.</p>
<p>In Python: <code>D &#61; A * B &#43; C</code></p>
<ol>
<li><p>Python first calculates <code>T &#61; A * B</code>, where <code>T</code> is a temporary array to store the result of the multiplication.</p>
</li>
<li><p>It then calculates the final array <code>D &#61; T &#43; C</code>.</p>
</li>
<li><p>This took two passes over the data and allocated a temporary array <code>T</code> of N-elements, which is then discarded. Allocating memory, especially large amounts of memory &#40;say ~ GBs&#41; signifantly impacts performance and may result in the calculation returning an &quot;Out of memory&quot; error.</p>
</li>
</ol>
<p>In Julia: <code>D &#61; A .* B .&#43; C</code></p>
<ol>
<li><p>Julia sees the &quot;chain of dots&quot; and performs loop fusion.</p>
</li>
<li><p>It knows you want to do <code>D&#91;i&#93; &#61; A&#91;i&#93; * B&#91;i&#93; &#43; C&#91;i&#93;</code> for every element.</p>
</li>
<li><p>It compiles this down to a single, performant for-loop that elimanates the need for the temporary array <code>T</code>.</p>
</li>
</ol>
<p>The above array expression is effectively:</p>
<pre><code class="language-julia-repl">julia&gt; # This is what Julia effectively runs:
julia&gt; D &#61; similar&#40;A&#41; # Allocate D *once*
julia&gt; for i in 1:length&#40;A&#41;
	D&#91;i&#93; &#61; A&#91;i&#93; * B&#91;i&#93; &#43; C&#91;i&#93;
end</code></pre>
<div class="admonition note"><p class="admonition-title">Note</p><p>In Julia, the array expression can also benefit from vectorization or single-instruction-multiple-data &#40;SIMD&#41;, where a single operation is simultaneously applied to multiple data. This will be discussed in more detail in session <em>2-4: Parallel-Computating</em>. It can also benefit from vector pipelining, where the multiply and add operations are performed simultaneously and in succession. That is, the multiplication operation is performed first on multiple values and the result is followed by the addition operation on multiple values. While the addition operation is being performed, the next multiplication operation is done, resulting in a multiplication-addition pipeline.</p>
</div>
</div>mimetext/htmlrootassigneelast_run_timestampA}QQzpersist_js_state·has_pluto_hook_features§cell_id$8a5d4ccf-a3b2-4373-822d-dbf5254bf4b0depends_on_disabled_cells§runtime еpublished_object_keysdepends_on_skipped_cells§errored±cell_dependencies $65151aba-d946-401d-8cca-1874f38146f2precedence_heuristic	cell_id$65151aba-d946-401d-8cca-1874f38146f2downstream_cells_mapupstream_cells_map@md_strgetindex$e26b69c9-d37d-449d-90d4-cdce4dff2362precedence_heuristic	cell_id$e26b69c9-d37d-449d-90d4-cdce4dff2362downstream_cells_mapupstream_cells_map@md_strgetindex$1416a80e-dbda-4185-8984-7f5de3c58f02precedence_heuristic	cell_id$1416a80e-dbda-4185-8984-7f5de3c58f02downstream_cells_mapupstream_cells_map@md_strgetindex$21190213-dc6e-4206-b516-338d5922b30eprecedence_heuristic	cell_id$21190213-dc6e-4206-b516-338d5922b30edownstream_cells_mapupstream_cells_map@md_strgetindex$d5268417-62f9-4fa8-beac-c4d4b9007223precedence_heuristic	cell_id$d5268417-62f9-4fa8-beac-c4d4b9007223downstream_cells_mapupstream_cells_map@md_strgetindex$346cb64d-3c89-44d1-9edb-06354152243aprecedence_heuristic	cell_id$346cb64d-3c89-44d1-9edb-06354152243adownstream_cells_mapupstream_cells_map@md_strgetindex$e3b1c6c2-5631-42c0-9a1b-d5a5520466c8precedence_heuristic	cell_id$e3b1c6c2-5631-42c0-9a1b-d5a5520466c8downstream_cells_mapupstream_cells_map@md_strgetindex$ff17e921-4522-4ab3-8282-9d9aafecdbe9precedence_heuristic	cell_id$ff17e921-4522-4ab3-8282-9d9aafecdbe9downstream_cells_mapupstream_cells_map@md_strgetindex$e022f21e-7f18-4690-99d4-0141403b3b38precedence_heuristic	cell_id$e022f21e-7f18-4690-99d4-0141403b3b38downstream_cells_mapupstream_cells_map@md_strgetindex$116911ed-cc32-41ea-a495-a3117815d669precedence_heuristic	cell_id$116911ed-cc32-41ea-a495-a3117815d669downstream_cells_mapupstream_cells_map@md_strgetindex$29e28885-d969-4e27-b5d3-866eb25302abprecedence_heuristic	cell_id$29e28885-d969-4e27-b5d3-866eb25302abdownstream_cells_mapupstream_cells_map@md_strgetindex$624bd571-c51e-4f52-848b-7cdefebbd42aprecedence_heuristiccell_id$624bd571-c51e-4f52-848b-7cdefebbd42adownstream_cells_mapDates$e984391b-0c01-4dc8-85aa-3593027e8530PlutoUIHypertextLiteralupstream_cells_mapTableOfContents$e984391b-0c01-4dc8-85aa-3593027e8530precedence_heuristic	cell_id$e984391b-0c01-4dc8-85aa-3593027e8530downstream_cells_mapupstream_cells_maptodayDates$624bd571-c51e-4f52-848b-7cdefebbd42aDates.format|>@dateformat_strMarkdown$11832b60-4906-4d22-960b-0b16b6634011precedence_heuristic	cell_id$11832b60-4906-4d22-960b-0b16b6634011downstream_cells_mapupstream_cells_map@md_strgetindex$30d5652d-605d-4119-b7e8-9cb8b93ce4a3precedence_heuristic	cell_id$30d5652d-605d-4119-b7e8-9cb8b93ce4a3downstream_cells_mapupstream_cells_map@md_strgetindex$2675d602-810c-4320-971c-902c3327a5cbprecedence_heuristic	cell_id$2675d602-810c-4320-971c-902c3327a5cbdownstream_cells_mapupstream_cells_map@md_strgetindex$8a5d4ccf-a3b2-4373-822d-dbf5254bf4b0precedence_heuristic	cell_id$8a5d4ccf-a3b2-4373-822d-dbf5254bf4b0downstream_cells_mapupstream_cells_map@md_strgetindexcell_execution_order $624bd571-c51e-4f52-848b-7cdefebbd42a$e984391b-0c01-4dc8-85aa-3593027e8530$2675d602-810c-4320-971c-902c3327a5cb$346cb64d-3c89-44d1-9edb-06354152243a$11832b60-4906-4d22-960b-0b16b6634011$21190213-dc6e-4206-b516-338d5922b30e$d5268417-62f9-4fa8-beac-c4d4b9007223$8a5d4ccf-a3b2-4373-822d-dbf5254bf4b0$65151aba-d946-401d-8cca-1874f38146f2$116911ed-cc32-41ea-a495-a3117815d669$29e28885-d969-4e27-b5d3-866eb25302ab$e26b69c9-d37d-449d-90d4-cdce4dff2362$e3b1c6c2-5631-42c0-9a1b-d5a5520466c8$30d5652d-605d-4119-b7e8-9cb8b93ce4a3$ff17e921-4522-4ab3-8282-9d9aafecdbe9$e022f21e-7f18-4690-99d4-0141403b3b38$1416a80e-dbda-4185-8984-7f5de3c58f02last_hot_reload_time        shortpath1-2: Arrays_1.jlprocess_statusreadypath>/home/runner/work/workshop/workshop/notebooks/1-2: Arrays_1.jlpluto_versionv0.20.24last_save_timeA}QMܪcell_order $e984391b-0c01-4dc8-85aa-3593027e8530$2675d602-810c-4320-971c-902c3327a5cb$346cb64d-3c89-44d1-9edb-06354152243a$11832b60-4906-4d22-960b-0b16b6634011$21190213-dc6e-4206-b516-338d5922b30e$d5268417-62f9-4fa8-beac-c4d4b9007223$8a5d4ccf-a3b2-4373-822d-dbf5254bf4b0$65151aba-d946-401d-8cca-1874f38146f2$116911ed-cc32-41ea-a495-a3117815d669$29e28885-d969-4e27-b5d3-866eb25302ab$e26b69c9-d37d-449d-90d4-cdce4dff2362$e3b1c6c2-5631-42c0-9a1b-d5a5520466c8$30d5652d-605d-4119-b7e8-9cb8b93ce4a3$ff17e921-4522-4ab3-8282-9d9aafecdbe9$e022f21e-7f18-4690-99d4-0141403b3b38$1416a80e-dbda-4185-8984-7f5de3c58f02$624bd571-c51e-4f52-848b-7cdefebbd42apublished_objectsnbpkginstall_time_ns   @instantiatedòinstalled_versionsDatesstdlibPlutoUI0.7.77HypertextLiteral0.9.5terminal_outputsDatesI
[0m[1mResolving...[22m
[90m===[39m
[36m[1m     Project[22m[39m No packages added to or removed from `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_fxubssvepk/Project.toml`
[32m[1m    Updating[22m[39m `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_fxubssvepk/Manifest.toml`
  [90m[14a3606d] [39m[93m↑ MozillaCACerts_jll v2025.5.20 ⇒ v2025.11.4[39m

[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mPrecompiling...[22m
[90m===[39m
Waiting for notebook process to start... Done. Starting precompilation...nbpkg_syncI
[0m[1mResolving...[22m
[90m===[39m
[36m[1m     Project[22m[39m No packages added to or removed from `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_fxubssvepk/Project.toml`
[32m[1m    Updating[22m[39m `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_fxubssvepk/Manifest.toml`
  [90m[14a3606d] [39m[93m↑ MozillaCACerts_jll v2025.5.20 ⇒ v2025.11.4[39m

[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mPrecompiling...[22m
[90m===[39m
Waiting for notebook process to start... Done. Starting precompilation...PlutoUII
[0m[1mResolving...[22m
[90m===[39m
[36m[1m     Project[22m[39m No packages added to or removed from `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_fxubssvepk/Project.toml`
[32m[1m    Updating[22m[39m `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_fxubssvepk/Manifest.toml`
  [90m[14a3606d] [39m[93m↑ MozillaCACerts_jll v2025.5.20 ⇒ v2025.11.4[39m

[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mPrecompiling...[22m
[90m===[39m
Waiting for notebook process to start... Done. Starting precompilation...HypertextLiteralI
[0m[1mResolving...[22m
[90m===[39m
[36m[1m     Project[22m[39m No packages added to or removed from `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_fxubssvepk/Project.toml`
[32m[1m    Updating[22m[39m `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_fxubssvepk/Manifest.toml`
  [90m[14a3606d] [39m[93m↑ MozillaCACerts_jll v2025.5.20 ⇒ v2025.11.4[39m

[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mPrecompiling...[22m
[90m===[39m
Waiting for notebook process to start... Done. Starting precompilation...enabled÷restart_recommended_msgrestart_required_msgbusy_packageswaiting_for_permission,waiting_for_permission_but_probably_disabled«cell_inputs $65151aba-d946-401d-8cca-1874f38146f2cell_id$65151aba-d946-401d-8cca-1874f38146f2codemd"""
# Matrix Multiplication ( `*` Operator)

We just learned that `A .* B` is the element-wise product.

So, how is matrix multiplication performed, as in linear algebra?

We use the asterisk (`*`) operator without the dot.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$e26b69c9-d37d-449d-90d4-cdce4dff2362cell_id$e26b69c9-d37d-449d-90d4-cdce4dff2362codeٜmd"""
# Problems
!!! tip "Remember that you can get help either through `?` in a REPL or with "Live Docs" right here in Pluto (lower right-hand corner)"
"""metadatashow_logsèdisabled®skip_as_script«code_folded$1416a80e-dbda-4185-8984-7f5de3c58f02cell_id$1416a80e-dbda-4185-8984-7f5de3c58f02codemd"""
## 5: Array Fusion
!!! warning ""
	* Create three 1D vectors, `a`, `b`, and `c`, each of length 4.
	* Using a single, "fused" broadcast expression, calculate $(a^2 + b)/c$.
	  - Note: `^` (carat) is the exponentiation operator.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$21190213-dc6e-4206-b516-338d5922b30ecell_id$21190213-dc6e-4206-b516-338d5922b30ecodemd"""
# Tuple Creation

Like Python, Julia has Tuples. Tuples differ from arrays in two aspects:

1. A Tuple is **immutable**. That means that once created the values cannot be changed.
2. A Tuple is **one-dimensional**.
2. A Tuple is **non-allocating**. Therefore, they have better performance that Arrays.

## Tuple Literals

Literal tuples are create by using `()` (paratheses) whose elements are separated by '`,`' (commas). For example:

```julia-repl
julia> t = (1, 2., "three")
(1, 2.0, "three")

julia> typeof(t)
Tuple{Int64, Float64, String}
```

## NamedTuples

Julia also has a named tuple type. They are basically identical to Tuples, except that the elements can have names or labels by preceeding the value with a character or string and an '`=`' (equal sign). For example:

```julia-repl
julia> n = (a=1, b=2, c="three")
(a = 1, b = 2, c = "three")
```

There is also a syntatic variation the begins with '`(;`' (parenthesis - semi-colon).

```julia-repl
julia> n = (; a=1, b=2, c="three")
(a = 1, b = 2, c = "three")
```

Tuples and NamedTuples can also be created using the `Tuple` and `NamedTuple` types. See the help documents for details.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$d5268417-62f9-4fa8-beac-c4d4b9007223cell_id$d5268417-62f9-4fa8-beac-c4d4b9007223codeCmd"""
# Broadcasting ( `.` Operator)

This is arguably the most important feature for clean, fast code using arrays or tuples.

## Arrays

What if you have a vector `A = [1, 2, 3]` and you want to add 1 to every element? Or what if you want to multiply every element in an array by its corresponding element in another array?

The `.` operator is a prefix operator that modifies the behavior of other operators such as `+` and `*`. It tells Julia to. perform an element-wise operation. The `.` operator is called the **broadcast** operator. As we will see in session 1-4, it applies to more than just arrays.

1. `A .+ 1` $\rightarrow$ `[2, 3, 4]`
2. `A .* B` means element-by-element multiplication.

## Tuples

The broadcast operator also applies to Tuples. For example:

```julia-repl
julia> (1, 2, 3) .+ (4, 5, 6)
(5, 7, 9)
```
"""metadatashow_logsèdisabled®skip_as_script«code_folded$346cb64d-3c89-44d1-9edb-06354152243acell_id$346cb64d-3c89-44d1-9edb-06354152243acode]md"""
# Matrix Protocol

Julia's arrays behave differently from arrays in languages like Python, C, or Java. Julia's design follows the conventions of mathematics and linear algebra, which has two major consequences.

1. 1-Based Indexing

   The first element of an array is at index 1.


   1. `my_vector[1]` is the first element.


   2. `my_matrix[1, 1]` is the top-left element.

   Python and C use 0-based indexing (where `my_array[0]` is the first element). This 1-based system may be more intuitive for mathematicians and scientists who are used to notation such as ``A_{ij}``, where $i$ and $j$ start at 1.


2. Column-Major Order

   This is one secret to Julia's performance. It describes how arrays are physically laid out in your computer's memory.


   1. Row-major order: Elements of a row are grouped together in memory. The computer stores [row1, row2, row3] (e.g., used by NumPy and C)


   2. Column-major order: Elements of a column are grouped together. The computer stores [col1, col2, col3]. (used by e.g., Julia, MATLAB, and FORTRAN)

Why does this matter? Accessing memory that is close together is typically much faster (due to CPU caching) than accessing memory that is spread out.

In Julia, this means that looping down a column, i.e., through the rows, is fast.

```julia-repl
julia> for j in 1:numCols
	for i in 1:numRows
		# Accessing memory sequentially is better, e.g.,
		A[i, j] ...
	end
end
```

!!! note
	`#` character begins a single comment, i.e., the comment string is between the `#` character and the newline character.

	`#=` and `=#` is a string block that can span multiple lines.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$e3b1c6c2-5631-42c0-9a1b-d5a5520466c8cell_id$e3b1c6c2-5631-42c0-9a1b-d5a5520466c8codemd"""
## 1: Array Construction
!!! warning ""
	* Construct a Vector using an array literal with the values 1, 2, 3.
	* Construct a 3×3 matrix using an array literal with 1, 2, 3 in the first row.
	* Construct a 3×3 matrix using an array literal with 1, 2, 3 in the first column.
	* Construct a 3×3 matrix of interger zeros.
	  - Hint: Use `zeros()`.
	* Construct a 3×3 matrix of Float32 ones.
	* Construct a 3×3 matrix of UInt8 filled with the value 8.
	  - Hint: Use `fill()`.
	* Construct a 3×3×3 array of Float32 whose values are undefined.
	  - Hint: Use `Array()` and `undef`.
	  - Note: This array allocates memory, but does not initilize it, saving time.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$ff17e921-4522-4ab3-8282-9d9aafecdbe9cell_id$ff17e921-4522-4ab3-8282-9d9aafecdbe9codemd"""
## 3: Broadcasting
!!! warning ""
	* Construct a 1D vector `x` containing five evenly spaced points from 0 to $\pi$, inclusive.
	  - Hint: Use `range()`.
	  - Note: `π` is a built-in constant.
	* Construct a 1D vector `y` containing five random values between 1 and 10.
	  - Hint: use `rand()`.
	* Multiply element-wise `x` and `y`.
	* Construct a third 1D vector `z` containing five values.
	* Evaluate the expression $x + y * z$
"""metadatashow_logsèdisabled®skip_as_script«code_folded$e022f21e-7f18-4690-99d4-0141403b3b38cell_id$e022f21e-7f18-4690-99d4-0141403b3b38code,md"""
## 4: Matrix Math vs. Element-wise Math
!!! warning ""
	* Create two 2×2 matrices:
	   - `X = [1 2; 3 4]`
	   - `Y = [2 0; 0 2] # This is a scaling matrix.`
	* Perform matrix multiplication on `X` and `Y`.
	* Perform element-wise multiplication on `X` and `Y`.
	* Are the results the same?
"""metadatashow_logsèdisabled®skip_as_script«code_folded$116911ed-cc32-41ea-a495-a3117815d669cell_id$116911ed-cc32-41ea-a495-a3117815d669codeMmd"""
```julia-repl
julia> A = [1 2; 3 4]
2×2 Matrix{Int64}:
 1  2
 3  4

julia> B = [5 6; 7 8]
2×2 Matrix{Int64}:
 5  6
 7  8
```

Element-wise multiplication

```julia-repl
julia> C = A .* B
2×2 Matrix{Int64}:
  5  12
 21  32
```

Matrix multiplication

```julia-repl
julia> D = A * B
2×2 Matrix{Int64}:
 19  22
 43  50
```
"""metadatashow_logsèdisabled®skip_as_script«code_folded$29e28885-d969-4e27-b5d3-866eb25302abcell_id$29e28885-d969-4e27-b5d3-866eb25302abcode|md"""
# Summary

!!! note ""
	* `[...]` is the syntax for a literal `Array` comprehension.
	* `(...)` is the syntax for a literal `Tuple` comprehension.
	* `(...=..., ...=...)` is the syntax for a literal `NamedTuple` comprehension.
	* `.*` (dot): broadcast operator, i.e., use for element-wide operations.
	* `*` (no dot): matix operator, i,e., use for matrix multiplication.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$624bd571-c51e-4f52-848b-7cdefebbd42acell_id$624bd571-c51e-4f52-848b-7cdefebbd42acodefbegin
	using Dates, PlutoUI, HypertextLiteral
	TableOfContents(title = "1-2: Arrays 1", depth = 4)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$e984391b-0c01-4dc8-85aa-3593027e8530cell_id$e984391b-0c01-4dc8-85aa-3593027e8530codet"""
!!! note "1-2: Arrays 1"
    **Last Updated: $(Dates.format(today(), dateformat"d u Y"))**
""" |> Markdown.parsemetadatashow_logsèdisabled®skip_as_script«code_folded$11832b60-4906-4d22-960b-0b16b6634011cell_id$11832b60-4906-4d22-960b-0b16b6634011codemd"""
# Array Creation

## Functions

You can create arrays with functions like `zeros(2, 3)` or `rand(3, 3)`, where the integers in parentheses specify the dimensions.

## Array Literals

For literal arrays, we use `[]` with two simple rules:

1. Commas (`,`) signify a 1D column Vector.
2. Spaces ( ) signify a 1D row Vector or a 1×N Matrix.

```julia-repl
julia> x = [1., 2., 3.]
3-element Vector{Float64}:
 1.0
 2.0
 3.0

julia> y = [1. 2. 3.]
1×3 Matrix{Float64}:
 1.0  2.0  3.0
```

## Semicolon Syntax

Semicolons (`;`) separate rows.

The four following examples show array creation:

1: A 1D Vector (using commas) produces a 3-element Vector{Int64}:

```julia-repl
julia> v = [1, 2, 3]
3-element Vector{Int64}:
 1
 2
 3
```

2: A 2D Matrix (using spaces for columns and semicolons for rows) produces a 2×3 Matrix{Int64}:

```julia-repl
julia> m = [1 2 3; 4 5 6]
2×3 Matrix{Int64}:
 1  2  3
 4  5  6
```

A 1x3 Row Vector (Matrix) produces a 1×3 Matrix{Int64}:
```julia-repl
julia> row_vec = [1 2 3]
1×3 Matrix{Int64}:
 1  2  3
```

A 3x1 Column Vector (Matrix) produces a 3×1 Matrix{Int64}:

```julia-repl
julia> col_vec = [1; 2; 3]
3-element Vector{Int64}:
 1
 2
 3
```

!!! note ""
	`[1, 2, 3]`, with commas, gives a 1D Vector, while `[1; 2; 3]`, with semicolons, gives a 2D, 3×1 Matrix. The 1D Vector is "dimensionless" and often acts like a column vector in math operations, which is very convenient.

## Array Elements

Array elements do not need to be homogeneous. They can be heterogeneous, meaning that they can have any type. For example:

```julia-repl
julia> a = [1, 2f0, "three", :four, nothing, missing]
4-element Vector{Any}:
 1
 2.0f0
  "three"
  :four
  nothing
  missing
```

!!! note
	The `nothing` value is of type `Nothing` and is synonymous with Python's `none` object. The `missing` value is of type `Missing` and means that the value is missing. Statistical functions will ignore the `missing` value during computations, unlike the `nothing` value, so the results will be statistically correct.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$30d5652d-605d-4119-b7e8-9cb8b93ce4a3cell_id$30d5652d-605d-4119-b7e8-9cb8b93ce4a3codeimd"""
## 2: Tuples and NamedTuples

!!! warning ""
	* Construct a Tuple literal `x` of three integers.
	* Construct a Tuple literal `y` of three floats.
	* Multiply `x` times `y`.
	* Construct a Tuple literal containing an integer, a float, and a string.
	* Construct a NamedTuple literal with labels `a`, `b`, and `c` and integer, float, and string values.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$2675d602-810c-4320-971c-902c3327a5cbcell_id$2675d602-810c-4320-971c-902c3327a5cbcodemd"""
# Multidimensional Arrays
In Julia, an array is a collection of objects stored in a multi-dimensional grid.

1. A 1D array is a Vector, i.e., as a single list or column of numbers.

2. A 2D array is a Matrix, i.e., rows and columns.

3. A 3D array is a cube of numbers, but of course one can keep going to 4D, 5D, or any number of dimensions.

We interact with these using square brackets `[]` for indexing, e.g., `A[2]` gets the second element of a vector. `M[2, 3]` gets the element at the second row, third column of a matrix.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$8a5d4ccf-a3b2-4373-822d-dbf5254bf4b0cell_id$8a5d4ccf-a3b2-4373-822d-dbf5254bf4b0codemd"""

# Array Fusion

This is where the magic happens and the power of Juila. What happens if you chain multiple "dotted" operations?

```julia-repl
julia> A = rand(1000)
julia> B = rand(1000)
julia> C = rand(1000)
julia> D = A .* B .+ C
```
Let's compare how Python (sp., Numpy) and Julia compare.

In Python: `D = A * B + C`

1. Python first calculates `T = A * B`, where `T` is a temporary array to store the result of the multiplication.
2. It then calculates the final array `D = T + C`.
3. This took two passes over the data and allocated a temporary array `T` of N-elements, which is then discarded. Allocating memory, especially large amounts of memory (say ~ GBs) signifantly impacts performance and may result in the calculation returning an "Out of memory" error.

In Julia: `D = A .* B .+ C`

1. Julia sees the "chain of dots" and performs loop fusion.
2. It knows you want to do `D[i] = A[i] * B[i] + C[i]` for every element.
3. It compiles this down to a single, performant for-loop that elimanates the need for the temporary array `T`.

The above array expression is effectively:

```julia-repl
julia> # This is what Julia effectively runs:
julia> D = similar(A) # Allocate D *once*
julia> for i in 1:length(A)
	D[i] = A[i] * B[i] + C[i]
end
```

!!! note
	In Julia, the array expression can also benefit from vectorization or single-instruction-multiple-data (SIMD), where a single operation is simultaneously applied to multiple data. This will be discussed in more detail in session *2-4: Parallel-Computating*. It can also benefit from vector pipelining, where the multiply and add operations are performed simultaneously and in succession. That is, the multiplication operation is performed first on multiple values and the result is followed by the addition operation on multiple values. While the addition operation is being performed, the next multiplication operation is done, resulting in a multiplication-addition pipeline.
"""metadatashow_logsèdisabled®skip_as_script«code_foldedënotebook_id$5aa5f9c8-45be-11f1-92c2-b1bdea3c73c9in_temp_dir¨metadata